﻿using System.Collections.Generic;
using Internal.KuiHuaBaoDian.Services.Battle;
using Internal.KuiHuaBaoDian.Services.Battle.Entity;
using KuiHuaBaoDian.Services.Battle.Data;
using KuiHuaBaoDian.Services.Battle.Entity;

namespace KuiHuaBaoDian.Services.Battle {

    /// <summary>
    /// 战斗服务
    /// </summary>
    public partial interface IBattleService {
    }

    /// <summary>
    /// 战斗服务
    /// </summary>
    public static class BattleService {

        /// <summary>
        /// 单例
        /// </summary>
        public static IBattleService Instance => m_Instance ??= KHBD.TypeMap.Instantiate<IBattleService>();
        private static IBattleService m_Instance;
    }

    [Implement(typeof(IBattleService))]
    internal sealed partial class KHBD_BattleService : IBattleService, IService, IBattleServiceInternal {

        void IService.OnApplicationQuit() { }

        private readonly List<IReadOnlyBattleFusionData.IItemFilter> m_FusionDataItemFilterList = new();

        void IBattleServiceInternal.RegisterFusionDataItemFilter(IReadOnlyBattleFusionData.IItemFilter filter) {
            m_FusionDataItemFilterList.Add(filter);
        }

        bool IBattleServiceInternal.ApplyFusionDataItemFilter(IEnumerable<IReadOnlyBattleFusionData.IItem> owner, IReadOnlyBattleFusionData.IItem item, IReadOnlyCollection<IReadOnlyBattleFusionData.IItem> takedItems) {
            foreach (var filter in m_FusionDataItemFilterList) {
                if (filter.IsIgnore(owner, item, takedItems)) {
                    return true;
                }
            }
            return false;
        }

        private readonly IDictionary<BattleEntityInstanceID, IBattleEntityRecord> m_EntityRecordDictionary = new Dictionary<BattleEntityInstanceID, IBattleEntityRecord>();
        private readonly IDictionary<BattleEntityType, IDictionary<BattleEntityInstanceID, IBattleEntityRecord>> m_TypeEntityRecordDictionary = new Dictionary<BattleEntityType, IDictionary<BattleEntityInstanceID, IBattleEntityRecord>>();

        public void AddEntity(BattleEntityInstanceID entityInstanceID, IBattleEntity entity) {
            if (!m_EntityRecordDictionary.ContainsKey(entityInstanceID)) {
                var record = KHBD.TypeMap.Instantiate<IBattleEntityRecord>();
                (record as IBattleEntityRecordInternal).Initialize(entity);
                m_EntityRecordDictionary.Add(entityInstanceID, record);
                if (!m_TypeEntityRecordDictionary.TryGetValue(entityInstanceID.ID.Type, out var typeEntityRecordDictionary)) {
                    typeEntityRecordDictionary = m_TypeEntityRecordDictionary[entityInstanceID.ID.Type] = new Dictionary<BattleEntityInstanceID, IBattleEntityRecord>();
                }
                typeEntityRecordDictionary.Add(entityInstanceID, record);
            }
        }

        public void RemoveEntity(BattleEntityInstanceID entityInstanceID) {
            if (m_EntityRecordDictionary.TryGetValue(entityInstanceID, out var reocrd)) {
                m_EntityRecordDictionary.Remove(entityInstanceID);
                var typeEntityRecordDictionary = m_TypeEntityRecordDictionary[entityInstanceID.ID.Type];
                typeEntityRecordDictionary.Remove(entityInstanceID);
            }
        }
    }
}

namespace Internal.KuiHuaBaoDian.Services.Battle {

    public interface IBattleServiceInternal {

        void RegisterFusionDataItemFilter(IReadOnlyBattleFusionData.IItemFilter filter);

        /// <summary>
        /// 应用过滤器
        /// </summary>
        /// <param name="owner">项拥有者</param>
        /// <param name="item">比对项</param>
        /// <param name="takedItems">已经忽略项</param>
        /// <returns>true忽略, false为未忽略</returns>
        bool ApplyFusionDataItemFilter(IEnumerable<IReadOnlyBattleFusionData.IItem> owner, IReadOnlyBattleFusionData.IItem item, IReadOnlyCollection<IReadOnlyBattleFusionData.IItem> takedItems);
    }
}